/******************************************************************************
 * 
 * Announce: CSharpKit, Basic algorithms, components and definitions.
 *           Copyright (C) ShenYongchen.
 *           All rights reserved.
 *   Author: 申永辰.郑州 (shenyczz@163.com)
 *  WebSite: http://github.com/shenyczz/CSharpKit
 *
 * THIS CODE IS LICENSED UNDER THE MIT LICENSE (MIT).
 * THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF 
 * ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
 * IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
 * PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
 * 
******************************************************************************/

namespace CSharpKit.SVM
{
    /// <summary>
    /// ONE_CLASS_QM
    /// </summary>
    internal class QM_ONE_CLASS : Kernel
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="prob">样本集</param>
        /// <param name="param">核参数</param>
        public QM_ONE_CLASS(SvmProblem prob, SvmParameter param)
            : base(prob.Count, prob.X, param)
        {
            // 1M = (1 << 20)
            cache = new Cache(prob.Count, (long)(param.CacheSize * (1 << 20)));
            QD = new double[prob.Count];
            for (int i = 0; i < prob.Count; i++)
            {
                QD[i] = KernelFunction(i, i);
            }
        }

        private readonly Cache cache;
        private readonly double[] QD;

        public override float[] GetQ(int i, int len)
        {
            float[] data;
            int start, j;
            if ((start = cache.GetData(i, out data, len)) < len)
            {
                for (j = start; j < len; j++)
                    data[j] = (float)KernelFunction(i, j);
            }
            return data;
        }

        public override double[] GetQD()
        {
            return QD;
        }

        public override void SwapIndex(int i, int j)
        {
            cache.SwapIndex(i, j);
            base.SwapIndex(i, j);
            do
            {
                double temp = QD[i];
                QD[i] = QD[j];
                QD[j] = temp;
            } while (false);
        }

        // void swap_index(int i, int j) const
        // {
        // 	cache->swap_index(i, j);
        // 	Kernel::swap_index(i, j);
        // 	swap(QD[i], QD[j]);
        // }
        // static inline void swap(T &x, T &y)
        // {
        //     T t = x;
        //     x = y;
        //     y = t;
        // }

        //}}@@@
    }


}
